// vim: set et sw=4 ts=4 sts=4 fdm=marker ff=unix fenc=utf8 nobomb:
/**
 * background.js
 *
 * @author mingcheng<i.feelinglucky#gmail.com>
 * @since  2009-11-24
 * @link   http://www.gracecode.com/
 */

void function() {
    var Y = YAHOO, Lang = Y.lang, 
        twitter_username, twitter_password, minutes = 5, requesting = false,
        channels = ['home', 'friends', 'mentions', 'favourite', 'direct'];

    /**
     * Init Environment for Request Tweets
     */
    var initEnvironment = function() {
        // get storage accouts info
        twitter_username = Helper.Conf.Get('twitter_username', '');
        twitter_password = Helper.Conf.Get('twitter_password', '');

        // generate configure for request tweets
        Twitter.setConfig({
                 api: Helper.Conf.Get('twitter_request_api', 'https://twitter.com'),
            username: twitter_username,
            password: twitter_password,
             timeout: Helper.Conf.Get('request_timeout_seconds', 5) * 1000,
               count: Helper.Conf.Get('request_count', '50')
        });

        // configure for tweets manager
        Tweets.setConfig({
            username: twitter_username
        });

        return true;
    }


    /**
     * Detcide whether is loggined
     */
    var isTwitterLogin = function() {
        var isLogin = !!(Helper.Status.Get('last_login_username') == twitter_username &&
            Helper.Status.Get('is_logined') == 'yes');

        if (!isLogin) {
            //Tweets.truncateTables();
            //console.error('Tweets.clearList error');
        }
        return isLogin ? true : false;
    }

    /**
     * The callback when login faild
     */
    var loginFaild = function() {
        console.error("user "+ twitter_username +" login faild");

        // clear status
        Helper.Status.Set('is_logined', 'no');
        Helper.Status.Set('last_login_username', '');
        Helper.Status.Set('last_login_time', 'no');

        // open config page for confirm inputed infomation
        chrome.tabs.create({url: 'options.html'});
    }


    /**
     * The callback when login success
     */
    var loginSuccess = function() {
        console.log("user "+ twitter_username +" login successful");

        // markup status
        Helper.Status.Set('is_logined', 'yes');
        Helper.Status.Set('last_login_username', twitter_username);
        Helper.Status.Set('last_login_time', +new Date);

        Server.restart(); // restart Server
    }


    /**
     * Login
     */
    var doTwitterLogin = function() {
        // if username or password format is illegal
        // open the config page for confrim
        if (!twitter_username || !twitter_password || !/^\w+/i.test(twitter_username)) {
            chrome.tabs.create({url: 'options.html'});
            return false;
        }

        // do login
        Twitter.login({
            onSuccess: function(o) {
                var result = JSON.parse(o.responseText);
                if (Lang.isUndefined(result.error)) {
                    // save logined user info to localStroage
                    Helper.Status.Set('twitter_info', JSON.stringify(result));
                    loginSuccess();
                } else {
                    loginFaild();
                }
            }, 

            onError: function(o) {
                loginFaild();
            }
        });
    }


    // 从 Twitter 上获取的数据顺序
    var Runner = (function() {
        var persist = true, idx = 0, getter = [
            {
                'name': 'home',
                'func': Twitter.getHomeTimeline
            },
            {
                'name': 'friends', 
                'func': Twitter.getFriendsTimeline
            },
            {
                'name': 'mentions',
                'func': Twitter.getMentions
            },
            {
                'name': 'favourite',
                'func': Twitter.getFavorite
            },
            {
                'name': 'direct',
                'func': Twitter.getDirectMessages
            }
        ];

         return {
            Reset: function() {
                idx = 0;
            },

            Sync: function () {
                // Build Elements for Popup.html
                /*
                Elements.build('friends',   Tweets.getCombo('timeline'));
                Elements.build('replies',   Tweets.getCombo('replies'));
                Elements.build('directs',   Tweets.getCombo('directs'));
                Elements.build('timeline',  Tweets.getCombo('timeline'));
                Elements.build('favourite', Tweets.getCombo('favourite'));
                */

                // Set unread number
                //var unreadNumber = parseInt(Tweets.getUnreadNum(), 10);
                //Helper.Func.setBadgeText(unreadNumber ? unreadNumber : '');
            },

            Request: function() {
                if (Lang.isObject(getter[idx])) {
                    var name = getter[idx].name, func = getter[idx++].func;
                    if (Lang.isFunction(func)) {
                        requesting = true;
                        func({
                            onSuccess: function(o) {
                                var data = JSON.parse(o.responseText);
                                for(var i = 0, len = data.length; i < len; i++) {
                                    var tmp = data[i];

                                    if (Lang.isObject(tmp.user)) {
                                        tmp.sender_id                = tmp.user.id;
                                        tmp.sender_profile_image_url = tmp.user.profile_image_url;
                                        tmp.sender_screen_name       = tmp.user.screen_name;
                                        tmp.sender_name              = tmp.user.name;
                                        delete tmp.user;   // trim user info

                                        // insert user infomation into database
                                        /*
                                        Tweets.addUser(tmp.user, {
                                            onSuccess: function(database) {
                                                console.info('adduser ok');
                                                // ...
                                            },
                                            onError:function(database, error) {
                                                console.error('database error: ' + error.message);
                                            }
                                        });
                                        // */
                                    }

                                    if (Lang.isObject(tmp.recipient)) {
                                        delete tmp.recipient;
                                    }

                                    if (Lang.isObject(tmp.sender)) {
                                        delete tmp.sender;
                                    }

                                    Tweets.addTweet(name, tmp, {
                                        onSuccess: function(database) {
                                            // ...
                                        },
                                        onError:function(database, error) {
                                            console.error('database error: ' + error.message);
                                        }
                                    }, true);
                                }

                                Runner.Request();
                            },
                            onError: function() {
                                console.error('get '+ name +' faild, maybe network timeout?');
                                if (persist) {
                                    Runner.Request();
                                } else {
                                    idx = 0;
                                    requesting = false;
                                    Runner.Sync(); // Sync data when all has done
                                }
                            }
                        });
                    }
                } else {
                    requesting = false; idx = 0;
                    Runner.Sync(); // Sync data when all has done
                }
            }
        };
    })();

    // Run as server 8~)
    var Server = (function() {
        var timer = null;

        /**
         * Request tweets from api
         */
        var requestTweets = function () {
            Helper.Status.Set('last_request_tweets', new Date);
            Runner.Request();
        };

        return {
            restart: function() {
                this.stop();
                this.start();
            },

            start: function() {
                // restart server when request is running
                if (this.status().running) {
                    this.restart();
                    return;
                }

                initEnvironment(); // init evnironment

                if (isTwitterLogin()) {
                    // open database for storage tweets
                    Tweets.openDatabase();

                    //Tweets.truncateTables();

                    // mark up badge text
                    Helper.Func.setBadgeText('?');

                    // request twieet each ? minutes
                    minutes = parseInt(Helper.Conf.Get('each_request_time', 5), 10);

                    // set timer for persist request
                    timer = Lang.later(minutes * 60 * 1000, Twitter, requestTweets, null, true);

                    // start request for first time
                    requestTweets();
                } else {

                    doTwitterLogin();
                }
            },

            stop: function() {
                if (timer) {
                    timer.cancel();
                    timer = false;
                    Runner.Reset();
                }
            },

            status: function() {
                return {
                    running: !!timer,
                    requesting: !!requesting
                }
            }
        };
    })();

    window.Server = Server;
    window.Sync = Runner.Sync;

    if (true || false) {
        chrome.tabs.create({url: 'popup.html'});
        chrome.tabs.create({url: 'options.html'});
    }
}();
